﻿#include "FITKOCCHDF5AdaptorOperGeometrySolid.h"

#include "FITKOCCHDF5AdaptorCommand.h"
#include "FITKOCCShapeIO.h"
// OCC
#include <TopoDS_Shape.hxx>

//Geommtry
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelBox.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelSphere.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelCylinder.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelOperSolid.h"

//Component
#include "FITK_Component/FITKGeoCompOCC/FITKAbstractOCCModel.h"

namespace IO
{
    // Reader.
   //@{

    QString FITKOCCHDF5AdaptorOperGeometrySolid::getAdaptorClass()
    {
        return "FITKOCCHDF5AdaptorOperGeometrySolid";
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::adaptR()
    {
        auto comm = dynamic_cast<Interface::FITKAbsGeoCommand*>(_dataObj);
        if (!_reader || !comm || !_h5Group) return false;
        return readOperGeometrySolid(comm, *_h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::adaptW()
    {
        auto comm = dynamic_cast<Interface::FITKAbsGeoCommand*>(_dataObj);
        if (!_writer || !comm || !_h5Group) return false;
        return writeOperGeometrySolid(comm, *_h5Group);
    }


    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolid(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        if (comm == nullptr) return false;
        //获取命令类型
        switch (comm->getGeometryCommandType())
        {
        case Interface::FITKGeoEnum::FGTBox:                        return readOperGeometrySolidBox(comm, h5Group);
        case Interface::FITKGeoEnum::FGTSphere:                     return readOperGeometrySolidSphere(comm, h5Group);
        case Interface::FITKGeoEnum::FGTCylinder:                   return readOperGeometrySolidCylinder(comm, h5Group);
        case Interface::FITKGeoEnum::FGTChamferSolid:               return readOperGeometrySolidChamfer(comm, h5Group);
        case Interface::FITKGeoEnum::FGTRemoveChamfer:              return readOperGeometrySolidRemoveChamfer(comm, h5Group);
        case Interface::FITKGeoEnum::FGTFilletSolid:                return readOperGeometrySolidFillet(comm, h5Group);
        case Interface::FITKGeoEnum::FGTRemoveFillet:               return readOperGeometrySolidRemoveFillet(comm, h5Group);
        case Interface::FITKGeoEnum::FGTDefeature:                  return readOperGeometrySolidDefeature(comm, h5Group);
        case Interface::FITKGeoEnum::FGTFillHole:                   return readOperGeometrySolidFillHole(comm, h5Group);
        case Interface::FITKGeoEnum::FGTClosedSurfaceSolid:         return readOperGeometrySolidClosedSurface(comm, h5Group);
        case Interface::FITKGeoEnum::FGTExtrudeSolid:               return readOperGeometrySolidExtrude(comm, h5Group);
        case Interface::FITKGeoEnum::FGTRevolSolid:                 return readOperGeometrySolidRevol(comm, h5Group);
        case Interface::FITKGeoEnum::FGTSweepSolid:                 return readOperGeometrySolidSweep(comm, h5Group);
        case Interface::FITKGeoEnum::FGTMultiSectionSolid:          return readOperGeometrySolidMultiSection(comm, h5Group);
        default: return false;
        }
        return true;
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolid(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        if (comm == nullptr) return false;
        //获取命令类型
        switch (comm->getGeometryCommandType())
        {
        case Interface::FITKGeoEnum::FGTBox:                        return writeOperGeometrySolidBox(comm, h5Group);
        case Interface::FITKGeoEnum::FGTSphere:                     return writeOperGeometrySolidSphere(comm, h5Group);
        case Interface::FITKGeoEnum::FGTCylinder:                   return writeOperGeometrySolidCylinder(comm, h5Group);
        case Interface::FITKGeoEnum::FGTChamferSolid:               return writeOperGeometrySolidChamfer(comm, h5Group);
        case Interface::FITKGeoEnum::FGTRemoveChamfer:              return writeOperGeometrySolidRemoveChamfer(comm, h5Group);
        case Interface::FITKGeoEnum::FGTFilletSolid:                return writeOperGeometrySolidFillet(comm, h5Group);
        case Interface::FITKGeoEnum::FGTRemoveFillet:               return writeOperGeometrySolidRemoveFillet(comm, h5Group);
        case Interface::FITKGeoEnum::FGTDefeature:                  return writeOperGeometrySolidDefeature(comm, h5Group);
        case Interface::FITKGeoEnum::FGTFillHole:                   return writeOperGeometrySolidFillHole(comm, h5Group);
        case Interface::FITKGeoEnum::FGTClosedSurfaceSolid:         return writeOperGeometrySolidClosedSurface(comm, h5Group);
        case Interface::FITKGeoEnum::FGTExtrudeSolid:               return writeOperGeometrySolidExtrude(comm, h5Group);
        case Interface::FITKGeoEnum::FGTRevolSolid:                 return writeOperGeometrySolidRevol(comm, h5Group);
        case Interface::FITKGeoEnum::FGTSweepSolid:                 return writeOperGeometrySolidSweep(comm, h5Group);
        case Interface::FITKGeoEnum::FGTMultiSectionSolid:          return writeOperGeometrySolidMultiSection(comm, h5Group);
        default: return false;
        }
        return true;
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidChamfer(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelChamferSolid* cSolid = dynamic_cast<Interface::FITKAbsGeoModelChamferSolid*>(comm);
        if (cSolid == nullptr) return false;

        int inputID = readIntAttribute(h5Group, "InputCmdID");
        cSolid->setInputCmdId(inputID);

        int edgesCount = readIntAttribute(h5Group, "Count");
        QList<int> edgesList;
        int* edges = new int[edgesCount];
        if (!readIntAttribute(h5Group, "Edges", edges, 1, edgesCount))
        {
            delete[] edges;
            return false;
        }
        for (int i = 0; i < edgesCount; i++)
        {
            edgesList.append(edges[i]);
        }
        delete[] edges;
        cSolid->setEdgeIds(edgesList);
        double distance = readDoubleAttribute(h5Group, "Distance");
        cSolid->setDistance(distance);
        return true;
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidChamfer(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelChamferSolid* cSolid = dynamic_cast<Interface::FITKAbsGeoModelChamferSolid*>(comm);
        if (cSolid == nullptr) return false;

        int inputID = cSolid->getInputCmdId();
        writeIntAttribute(h5Group, "InputCmdID", &inputID);

        auto edges = cSolid->getEgdeIds();
        int edgesCount = edges.size();
        writeIntAttribute(h5Group, "Count", &edgesCount);
        writeIntAttribute(h5Group, "Edges", &edges, 1, edgesCount);
        double distance = cSolid->getDistance();
        writeDoubleAttribute(h5Group, "Distance", &distance);
        return true;
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidFillet(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelFilletSolid* fSolid = dynamic_cast<Interface::FITKAbsGeoModelFilletSolid*>(comm);
        if (fSolid == nullptr) return false;

        int inputID = readIntAttribute(h5Group, "InputCmdID");
        fSolid->setInputCmdId(inputID);

        int edgesCount = readIntAttribute(h5Group, "Count");
        QList<int> edgesList;
        int* edges = new int[edgesCount];
        if (!readIntAttribute(h5Group, "Edges", edges, 1, edgesCount))
        {
            delete[] edges;
            return false;
        }
        for (int i = 0; i < edgesCount; i++)
        {
            edgesList.append(edges[i]);
        }
        delete[] edges;
        fSolid->setEdgeIds(edgesList);
        double radius = readDoubleAttribute(h5Group, "Radius");
        fSolid->setRadius(radius);
        return true;
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidFillet(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelFilletSolid* fSolid = dynamic_cast<Interface::FITKAbsGeoModelFilletSolid*>(comm);
        if (fSolid == nullptr) return false;

        int inputID = fSolid->getInputCmdId();
        writeIntAttribute(h5Group, "InputCmdID", &inputID);

        auto edges = fSolid->getEgdeIds();
        int edgesCount = edges.size();
        writeIntAttribute(h5Group, "Count", &edgesCount);
        writeIntAttribute(h5Group, "Edges", &edges, 1, edgesCount);
        double radius = fSolid->getRadius();
        writeDoubleAttribute(h5Group, "Radius", &radius);
        return true;
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidRemoveChamfer(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelRemoveChamferSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelRemoveChamferSolid*>(comm);
        if (rSolid == nullptr) return false;
        return readOperGeometrySolidDefeature(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidRemoveChamfer(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelRemoveChamferSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelRemoveChamferSolid*>(comm);
        if (rSolid == nullptr) return false;
        return writeOperGeometrySolidDefeature(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidRemoveFillet(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelRemoveFilletSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelRemoveFilletSolid*>(comm);
        if (rSolid == nullptr) return false;
        return readOperGeometrySolidDefeature(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidRemoveFillet(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelRemoveFilletSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelRemoveFilletSolid*>(comm);
        if (rSolid == nullptr) return false;
        return writeOperGeometrySolidDefeature(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidDefeature(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelDefeatureSolid* dSolid = dynamic_cast<Interface::FITKAbsGeoModelDefeatureSolid*>(comm);
        if (dSolid == nullptr) return false;

        int inputID = readIntAttribute(h5Group, "InputCmdID");
        dSolid->setInputCmdId(inputID);

        int facesCount = readIntAttribute(h5Group, "Count");
        QList<int> facesList;
        int* faces = new int[facesCount];
        if (!readIntAttribute(h5Group, "Faces", faces, 1, facesCount))
        {
            delete[] faces;
            return false;
        }
        for (int i = 0; i < facesCount; i++)
        {
            facesList.append(faces[i]);
        }
        delete[] faces;
        dSolid->setFaceIds(facesList);
        return true;
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidDefeature(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelDefeatureSolid* dSolid = dynamic_cast<Interface::FITKAbsGeoModelDefeatureSolid*>(comm);
        if (dSolid == nullptr) return false;

        int inputID = dSolid->getInputCmdId();
        writeIntAttribute(h5Group, "InputCmdID", &inputID);

        auto faces = dSolid->getFaceIds();
        int faccesCount = faces.size();
        writeIntAttribute(h5Group, "Count", &faccesCount);
        writeIntAttribute(h5Group, "Faces", &faces, 1, faccesCount);
        return true;
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidFillHole(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelFillHoleSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelFillHoleSolid*>(comm);
        if (rSolid == nullptr) return false;
        return readOperGeometrySolidDefeature(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidFillHole(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelFillHoleSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelFillHoleSolid*>(comm);
        if (rSolid == nullptr) return false;
        return writeOperGeometrySolidDefeature(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidBase(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelSolid*>(comm);
        if (rSolid == nullptr) return false;
        return true;
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidBase(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelSolid*>(comm);
        if (rSolid == nullptr) return false;
        return true;
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidClosedSurface(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelClosedSurfaceSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelClosedSurfaceSolid*>(comm);
        if (rSolid == nullptr) return false;
        int count = readIntAttribute(h5Group, "Count");
        for (int i = 0; i < count; i++)
        {
            int faceArray[2];
            writeIntAttribute(h5Group, std::to_string(i), faceArray, 1, 3);
            Interface::VirtualShape vshape;
            vshape.CmdId = faceArray[0];
            vshape.VirtualTopoId = faceArray[1];
            rSolid->addFace(vshape);
        }
        return readOperGeometrySolidBase(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidClosedSurface(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelClosedSurfaceSolid* csSolid = dynamic_cast<Interface::FITKAbsGeoModelClosedSurfaceSolid*>(comm);
        if (csSolid == nullptr) return false;

        auto faces = csSolid->faces();
        int count = faces.size();
        for (int i = 0; i < count; i++)
        {
            auto face = faces[i];
            int faceArray[2]{ face.CmdId, face.VirtualTopoId };
            writeIntAttribute(h5Group, std::to_string(i), faceArray, 1, 3);
        }
        writeIntAttribute(h5Group, "Count", &count);
        return writeOperGeometrySolidBase(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidExtrude(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelExtrudeSolid* eSolid = dynamic_cast<Interface::FITKAbsGeoModelExtrudeSolid*>(comm);
        if (eSolid == nullptr) return false;

        auto sourceSurface = eSolid->sourceSurface();
        int sourceSurfaceArray[2];
        double directionArray[3];
        if (!readIntAttribute(h5Group, "SourceSurface", sourceSurfaceArray, 1, 2)) return false;
        Interface::VirtualShape vShape;
        vShape.CmdId = sourceSurfaceArray[0];
        vShape.VirtualTopoId = sourceSurfaceArray[1];
        eSolid->setSourceSurface(vShape);

        if (!readDoubleAttribute(h5Group, "Direction", directionArray, 1, 3)) return false;
        eSolid->setDirection(directionArray[0], directionArray[1], directionArray[2]);
        double length = readDoubleAttribute(h5Group, "Length");
        eSolid->setLength(length);

        return readOperGeometrySolidBase(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidExtrude(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelExtrudeSolid* eSolid = dynamic_cast<Interface::FITKAbsGeoModelExtrudeSolid*>(comm);
        if (eSolid == nullptr) return false;

        auto sourceSurface = eSolid->sourceSurface();
        int sourceSurfaceArray[2]{ sourceSurface.CmdId,sourceSurface.VirtualTopoId };
        writeIntAttribute(h5Group, "SourceSurface", sourceSurfaceArray, 1, 2);

        auto direction = eSolid->direction();
        double directionArray[3]{ direction[0],direction[1],direction[2] };
        writeDoubleAttribute(h5Group, "Direction", directionArray, 1, 3);
        double length = eSolid->length();
        writeDoubleAttribute(h5Group, "Length", &length);

        return writeOperGeometrySolidBase(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidRevol(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelRevolSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelRevolSolid*>(comm);
        if (rSolid == nullptr) return false;

        int sourceSurfaceArray[2];
        double rotateAxisPoint1[3], rotateAxisPoint2[3];
        if (!readIntAttribute(h5Group, "SourceSurface", sourceSurfaceArray, 1, 2)) return false;
        Interface::VirtualShape vShape;
        vShape.CmdId = sourceSurfaceArray[0];
        vShape.VirtualTopoId = sourceSurfaceArray[1];
        rSolid->setSourceSurface(vShape);

        if (!readDoubleAttribute(h5Group, "RotateAxisPoint1", rotateAxisPoint1, 1, 3)) return false;
        rSolid->setRotateAxisPoint1(rotateAxisPoint1[0], rotateAxisPoint1[1], rotateAxisPoint1[2]);

        if (!readDoubleAttribute(h5Group, "RotateAxisPoint2", rotateAxisPoint2, 1, 3)) return false;
        rSolid->setRotateAxisPoint2(rotateAxisPoint2[0], rotateAxisPoint2[1], rotateAxisPoint2[2]);

        return readOperGeometrySolidBase(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidRevol(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelRevolSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelRevolSolid*>(comm);
        if (rSolid == nullptr) return false;

        auto sourceSurface = rSolid->sourceSurface();
        int sourceSurfaceArray[2]{ sourceSurface.CmdId,sourceSurface.VirtualTopoId };
        writeIntAttribute(h5Group, "SourceSurface", sourceSurfaceArray, 1, 2);

        std::array<double, 3>  rotateAxisPoint1 = rSolid->rotateAxisPoint1();
        double rotateAxisPoint1Array[3]{ rotateAxisPoint1[0], rotateAxisPoint1[1], rotateAxisPoint1[2] };
        writeDoubleAttribute(h5Group, "RotateAxisPoint1", rotateAxisPoint1Array, 1, 3);

        std::array<double, 3>  rotateAxisPoint2 = rSolid->rotateAxisPoint2();
        double rotateAxisPoint2Array[3]{ rotateAxisPoint2[0], rotateAxisPoint2[1], rotateAxisPoint2[2] };
        writeDoubleAttribute(h5Group, "RotateAxisPoint2", rotateAxisPoint2Array, 1, 3);

        return writeOperGeometrySolidBase(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidSweep(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelSweepSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelSweepSolid*>(comm);
        if (rSolid == nullptr) return false;
        int profileArray[2], curveArray[2];
        if (!readIntAttribute(h5Group, "Profile", profileArray, 1, 2)) return false;
        Interface::VirtualShape profile;
        profile.CmdId = profileArray[0];
        profile.VirtualTopoId = profileArray[1];
        rSolid->setProfile(profile);

        if (!readIntAttribute(h5Group, "Curve", curveArray, 1, 2)) return false;
        Interface::VirtualShape curve;
        curve.CmdId = curveArray[0];
        curve.VirtualTopoId = curveArray[1];
        rSolid->setCurve(curve);

        return readOperGeometrySolidBase(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidSweep(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelSweepSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelSweepSolid*>(comm);
        if (rSolid == nullptr) return false;

        auto profile = rSolid->profile();
        int profileArray[2]{ profile.CmdId,profile.VirtualTopoId };
        writeIntAttribute(h5Group, "Profile", profileArray, 1, 2);

        auto curve = rSolid->curve();
        int curveArray[2]{ curve.CmdId,curve.VirtualTopoId };
        writeIntAttribute(h5Group, "Curve", curveArray, 1, 2);

        return writeOperGeometrySolidBase(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::readOperGeometrySolidMultiSection(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelMultiSectionSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelMultiSectionSolid*>(comm);
        if (rSolid == nullptr) return false;

        int count = readIntAttribute(h5Group, "Count");
        int sectionArray[2];
        for (int i = 0; i < count; i++)
        {
            if (!readIntAttribute(h5Group, std::to_string(i), sectionArray, 1, 2)) return false;
            Interface::VirtualShape section;
            section.CmdId = sectionArray[0];
            section.VirtualTopoId = sectionArray[1];
            rSolid->addSection(section);
        }
        return writeOperGeometrySolidBase(comm, h5Group);
    }

    bool FITKOCCHDF5AdaptorOperGeometrySolid::writeOperGeometrySolidMultiSection(Interface::FITKAbsGeoCommand * comm, H5::Group & h5Group)
    {
        Interface::FITKAbsGeoModelMultiSectionSolid* rSolid = dynamic_cast<Interface::FITKAbsGeoModelMultiSectionSolid*>(comm);
        if (rSolid == nullptr) return false;

        auto sections = rSolid->sections();
        int count = sections.size();
        for (int i = 0; i < count; i++)
        {
            auto section = sections[i];
            int sectionArray[2]{ section.CmdId,section.VirtualTopoId };
            writeIntAttribute(h5Group, std::to_string(i), sectionArray, 1, 2);
        }
        writeIntAttribute(h5Group, "Count", &count);
        return writeOperGeometrySolidBase(comm, h5Group);
    }

    //@}
}   // namespace IO
